package org.bits.ui;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

import javax.swing.*;
import javax.swing.border.TitledBorder;

import org.bits.common.IconConstants;
import org.bits.common.model.ItemTableModel;
import org.bits.data.*;
import org.bits.model.DataAccessModel;

/*******************************************************************************
 * 
 ******************************************************************************/
public class FindingView
{
    /**  */
    private static final String[] COL_HEADINGS = { "Product", "Release",
        "Build" };
    /**  */
    private static final Class<?>[] COL_CLASSES = { Product.class,
        Release.class, String.class };

    /**  */
    private JPanel panel;
    /**  */
    private JTextField numberField;
    /**  */
    private JTextField titleField;
    /**  */
    private JEditorPane descriptionField;
    /**  */
    private JTable productsTable;
    /**  */
    private ProductsTableModel productsModel;

    /**  */
    private boolean isNew;
    /**  */
    private DataAccessModel dataModel;
    /**  */
    private Finding finding;

    /***************************************************************************
     * 
     **************************************************************************/
    public FindingView( DataAccessModel dataModel )
    {
        this( dataModel, false );
    }

    /***************************************************************************
     * @param isNew
     **************************************************************************/
    public FindingView( DataAccessModel dataModel, boolean isNew )
    {
        this.dataModel = dataModel;
        this.isNew = isNew;

        numberField = new JTextField( 20 );
        titleField = new JTextField( 20 );
        descriptionField = new JEditorPane();
        productsModel = new ProductsTableModel();
        productsTable = new JTable( productsModel );

        panel = createFormPanel();
    }

    /***************************************************************************
     * @return
     **************************************************************************/
    private JPanel createFormPanel()
    {
        JPanel panel = new JPanel( new GridBagLayout() );
        JScrollPane descriptionPane = new JScrollPane( descriptionField );
        JLabel numberLabel = new JLabel( "Number" );
        GridBagConstraints constraints;

        numberLabel.setVisible( !isNew );
        numberField.setEditable( false );
        numberField.setVisible( !isNew );

        descriptionPane.setPreferredSize( new Dimension( 300, 200 ) );
        descriptionPane.setMinimumSize( new Dimension( 300, 200 ) );

        constraints = new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 4, 4,
                2, 4 ), 0, 0 );
        panel.add( numberLabel, constraints );
        constraints = new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 2, 4,
                4, 4 ), 0, 0 );
        panel.add( numberField, constraints );

        constraints = new GridBagConstraints( 0, 2, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 4, 4,
                2, 4 ), 0, 0 );
        panel.add( new JLabel( "Title" ), constraints );
        constraints = new GridBagConstraints( 0, 3, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(
                2, 4, 4, 4 ), 0, 0 );
        panel.add( titleField, constraints );

        constraints = new GridBagConstraints( 0, 4, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(
                0, 0, 0, 0 ), 0, 0 );
        panel.add( createProductsPanel(), constraints );

        constraints = new GridBagConstraints( 0, 5, 1, 1, 0.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 4, 4,
                2, 4 ), 0, 0 );
        panel.add( new JLabel( "Description" ), constraints );
        constraints = new GridBagConstraints( 0, 6, 1, 1, 1.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(
                2, 4, 4, 4 ), 0, 0 );
        panel.add( descriptionPane, constraints );

        constraints = new GridBagConstraints( 0, 25, 1, 1, 1.0, 1.0,
            GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets( 0, 0,
                0, 0 ), 0, 0 );
        panel.add( Box.createVerticalStrut( 0 ), constraints );

        return panel;
    }

    /***************************************************************************
     * @return
     **************************************************************************/
    private JPanel createProductsPanel()
    {
        JPanel panel = new JPanel( new GridBagLayout() );
        JToolBar toolbar = new JToolBar();
        JScrollPane tablePane = new JScrollPane( productsTable );
        JButton button;
        GridBagConstraints constraints;

        button = new JButton(
            IconConstants.loader.getIcon( IconConstants.EDIT_ADD_16 ) );
        button.setToolTipText( "Add Product" );
        button.addActionListener( new AddButtonListener() );
        toolbar.add( button );

        button = new JButton(
            IconConstants.loader.getIcon( IconConstants.EDIT_16 ) );
        button.setToolTipText( "Modify Product" );
        button.addActionListener( new ModifyButtonListener() );
        toolbar.add( button );

        button = new JButton(
            IconConstants.loader.getIcon( IconConstants.EDIT_DELETE_16 ) );
        button.setToolTipText( "Delete Product" );
        button.addActionListener( new DeleteButtonListener() );
        toolbar.add( button );

        toolbar.setBorderPainted( false );
        toolbar.setFloatable( false );
        toolbar.setRollover( true );

        Dimension dim = new Dimension( 100, 100 );

        tablePane.setMinimumSize( dim );
        tablePane.setMaximumSize( dim );
        tablePane.setPreferredSize( dim );

        constraints = new GridBagConstraints( 0, 0, 1, 1, 1.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(
                0, 0, 0, 0 ), 0, 0 );
        panel.add( toolbar, constraints );
        constraints = new GridBagConstraints( 0, 1, 1, 1, 1.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(
                0, 0, 0, 0 ), 0, 0 );
        panel.add( tablePane, constraints );

        panel.setBorder( new TitledBorder( "Products" ) );

        return panel;
    }

    /***************************************************************************
     * @return
     **************************************************************************/
    public JPanel getView()
    {
        return panel;
    }

    /***************************************************************************
     * 
     **************************************************************************/
    private class AddButtonListener implements ActionListener
    {
        @Override
        public void actionPerformed( ActionEvent e )
        {
            VersionDialog vd = new VersionDialog( dataModel,
                dataModel.getProducts(),
                SwingUtilities.getWindowAncestor( panel ), "" );

            Version v = vd.showVersionDialog();

            if( v != null )
            {
                productsModel.addItem( v );
            }
        }
    }

    /***************************************************************************
     * 
     **************************************************************************/
    private class ModifyButtonListener implements ActionListener
    {
        @Override
        public void actionPerformed( ActionEvent e )
        {
            int row = productsTable.getSelectedRow();

            if( row > -1 )
            {
                VersionDialog vd = new VersionDialog( dataModel,
                    dataModel.getProducts(),
                    SwingUtilities.getWindowAncestor( panel ), "" );
                Version v = productsModel.getItem( row );

                vd.setVersion( v );
                vd.showVersionDialog();
            }
        }
    }

    /***************************************************************************
     * 
     **************************************************************************/
    private class DeleteButtonListener implements ActionListener
    {
        @Override
        public void actionPerformed( ActionEvent e )
        {
            int row = productsTable.getSelectedRow();

            if( row > -1 )
            {
                productsModel.removeItem( row );
            }
        }
    }

    /***************************************************************************
     * 
     **************************************************************************/
    private class ProductsTableModel extends ItemTableModel<Version>
    {
        public ProductsTableModel()
        {
            setColumnClasses( Arrays.asList( COL_CLASSES ) );
            setColumnNames( Arrays.asList( COL_HEADINGS ) );
        }

        @Override
        public Object getValueAtColumn( Version prod, int col )
        {
            switch( col )
            {
                case 0:
                    return prod.product;

                case 1:
                    return prod.release;

                case 2:
                    return prod.build;
            }

            throw new IllegalArgumentException( "Unknown column:" + col );
        }
    }

    public Finding getFinding()
    {
        return finding;
    }

    public void setFinding( Finding finding )
    {
        this.finding = finding;

        numberField.setText( "" + finding.number );
        titleField.setText( finding.title );
        descriptionField.setText( finding.description );
    }

    public void apply()
    {
        finding.title = titleField.getText();
        finding.description = descriptionField.getText();
    }
}
